﻿//
//  Copyright (c) 2011 Extreme: Paweł Huryn (lead), Jakub Domański
//

using System;
using Microsoft.SharePoint;

namespace Extreme.SPFramework.DomainModel
{
    /// <summary>
    /// Memory-leak safe, auto disposing wrapper for SPWeb, SPSite pair.
    /// It is required in scenario, when calling method gets SPWeb from another class.
    /// 
    /// For example:
    /// 
    /// using(var web = someClass.GetWeb())
    /// {
    ///     // use web, do some code
    /// }
    /// will dispose SPWeb but not SPSite!
    /// 
    /// In this scenario you need to use:
    /// 
    /// using(var webSite = someClass.GetWebSite())
    /// {
    ///     SPWeb web = webSite.Web;
    ///     // use web, do some code
    /// }
    /// 
    /// Furthmore, AutoDisposeWebSite disposes all unmanaged resources in destructor, 
    /// so that (it is not recommended practice!) you do not need to call Dispose() at all.
    /// </summary>
    public class AutoDisposeWebSite : IDisposable
    {
        private readonly SPSite site;
        private readonly SPWeb web;
        private bool disposed = false;

        /// <summary>
        /// Creates new instance of AutoDisposeWebSite
        /// </summary>
        /// <param name="site">SPSite to wrap</param>
        /// <param name="web">SPWeb to wrap</param>
        public AutoDisposeWebSite(SPSite site, SPWeb web)
        {
            if(site == null)
                throw new ArgumentNullException("site");
            if(web == null)
                throw new ArgumentException("web");

            this.site = site;
            this.web = web;
        }

        ~AutoDisposeWebSite()
        {
            Dispose(false);
        }

        /// <summary>
        /// Gets wrapped SPWeb
        /// </summary>
        public SPWeb Web
        {
            get { return web; }
        }

        /// <summary>
        /// Gets wrapped SPSite
        /// </summary>
        public SPSite Site
        {
            get { return site; }
        }

        /// <summary>
        /// Disposes all unmanaged resources
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
        }

        /// <summary>Disposes all unmanaged resources</summary>
        /// <param name="disposing">Not used, due to good programming practice</param>
        private void Dispose(bool disposing)
        {
            if(!disposed)
            {
                disposed = true;
                web.Dispose();
                site.Dispose();
            }
        }
    }
}
